#!/usr/bin/env python3
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.

from collections.abc import Mapping

import pytest

from cmk.agent_based.v2 import CheckResult, Metric, Result, Service, State, StringTable
from cmk.plugins.mssql.agent_based.mssql_jobs import (
    check_mssql_jobs,
    discover_mssql_jobs,
    parse_mssql_jobs,
)

_STRING_TABLE_SINGLE_INSTANCE_SINGLE_NO_SCHEDULE_ENABLED_JOB: StringTable = [
    ["MSSQLSERVER"],
    [
        "{2C32E575-3C76-48E0-9E04-43BD2A15B2E1}",
        "teststsssss",
        "1",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2021-02-08 07:38:50",
    ],
]


def _make_job(*, enabled: bool, scheduled: bool) -> StringTable:
    return [
        ["MSSQLSERVER"],
        [
            "{2C32E575-3C76-48E0-9E04-43BD2A15B2E1}",
            "teststsssss",
            "1" if enabled else "",
            "",
            "",
            "5",
            "",
            "0",
            "0",
            "0",
            "1" if scheduled else "",
            "2021-02-08 07:38:50",
        ],
    ]


_STRING_TABLE_SINGLE_INSTANCE_SINGLE_NO_SCHEDULE_DISABLED_JOB = [
    ["MSSQLSERVER"],
    [
        "{2C32E575-3C76-48E0-9E04-43BD2A15B2E1}",
        "teststsssss",
        "0",
        "20200929",
        "300",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2021-02-08 07:38:50",
    ],
]

_STRING_TABLE_SINGLE_INSTANCE_SINGLE_WITH_SCHEDULE_ENABLED_JOB = [
    ["MSSQLSERVER"],
    [
        "{2C32E575-3C76-48E0-9E04-43BD2A15B2E1}",
        "teststsssss",
        "1",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "1",
        "2021-02-08 07:38:50",
    ],
]

_STRING_TABLE_SINGLE_INSTANCE_MULTIPLE_JOBS = [
    [
        "MSSQLSERVER",
    ],
    [
        "{CB09DA64-FBBD-46A0-9CD4-02D609249DE4}",
        "täglich 00:03",
        "1",
        "20200929",
        "300",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 55 (täglich 00:03).  The last step to run was step 2 (Tagesstatistik Listentool).",
        "20200928",
        "300",
        "35",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{DD63E68D-61FF-42CB-9986-0B00276611EE}",
        "4x Täglich Infomanagement",
        "1",
        "20200929",
        "63333",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 126 (4x Täglich ab 06:30 Uhr).  The last step to run was step 1 (auto_importAll).",
        "20200928",
        "123333",
        "745",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{E185714E-1231-4A02-88E5-21D521DE6A61}",
        "Wartung Stündlich",
        "1",
        "20200928",
        "161500",
        "0",
        "The job failed.  JobManager tried to run a non-existent step (3) for job Wartung Stündlich.",
        "20200928",
        "151500",
        "9",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{76F94409-DDB4-4F9B-9AE2-3AF23AF46C48}",
        "1x Täglich",
        "1",
        "20200929",
        "32000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 43 (Mo-Sa 03:20).  The last step to run was step 18 (Abgleich MAV).",
        "20200928",
        "32000",
        "10806",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{4B9D1121-FDEF-4CA5-A202-4ED8B0421230}",
        "aller 2h",
        "1",
        "20200928",
        "170500",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 48 (Mo-Sa 07:00 aller 2h).  The last step to run was step 2 (Magicinfo_Device_IP).",
        "20200928",
        "150501",
        "1245",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{11E5BEA3-6925-45F7-B67B-5B954F11153A}",
        "Wartung Täglich",
        "1",
        "20200929",
        "14500",
        "0",
        "The job failed.  JobManager tried to run a non-existent step (3) for job Wartung Täglich.",
        "20200928",
        "14500",
        "341",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{783F8CB4-A09A-409A-BFBF-6822589DFA50}",
        "1x Täglich 6:00 Uhr",
        "1",
        "20200929",
        "60101",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 84 (Mo-So 6:00 Uhr).  The last step to run was step 2 (C2C_Export_OptIn).",
        "20200928",
        "60101",
        "43",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{A58A7683-E8CF-446B-AED7-6A60D8E29FE0}",
        "1x Täglich Infomanagement",
        "1",
        "20200929",
        "21700",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 61 (Mo-So 02:17).  The last step to run was step 1 (Quali AUTO MAIN).",
        "20200928",
        "21700",
        "3628",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{32267254-2240-474F-92D1-806FDBBC036E}",
        "Sonntag",
        "1",
        "20201004",
        "73400",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 60 (Sonntag).  The last step to run was step 1 (LdapImportActiveDirectory).",
        "20200927",
        "73400",
        "134",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{03013FF0-175C-4492-9C03-89AD3A05926C}",
        "SSIS Server Maintenance Job",
        "1",
        "20200929",
        "0",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 10 (SSISDB Scheduler).  The last step to run was step 2 (SSIS Server Max Version Per Project Maintenance).",
        "20200928",
        "0",
        "2",
        "0",
        "2020-09-28 15:37:36",
    ],
    [
        "{000B84B2-F29F-422A-8C89-BFE84696918F}",
        "aller 1h",
        "1",
        "20200928",
        "153500",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 47 (Mo-Sa 05:30 aller 1h).  The last step to run was step 4 (Outbound IBI/PIC).",
        "20200928",
        "153500",
        "45",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{FD3904A7-A6A3-48A2-B5C7-C6AFAE646966}",
        "1 x täglich 01:00 Uhr",
        "1",
        "20200929",
        "10000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 261 (täglich 01:00 Uhr).  The last step to run was step 2 (C2C Import AIC).",
        "20200928",
        "10000",
        "43",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{99B511D3-A808-4B50-8C57-C962B4E5DA55}",
        "1x täglich ttCall",
        "0",
        "20200929",
        "53000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 173 (ttCall).  The last step to run was step 1 (Projekt Vorausverfügung-Veraltete Daten disablen).",
        "20200928",
        "53000",
        "1",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{C31ED308-A554-40A0-B10A-CB06988FEDA5}",
        "aller 15 min",
        "1",
        "20200928",
        "153005",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 77 (CMS Import).  The last step to run was step 1 (CMS Intervall Import).",
        "20200928",
        "153005",
        "34",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{54DBA242-E5AA-4A45-8ABB-D166C1493170}",
        "aller 5 min",
        "1",
        "20200928",
        "152934",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 255 (aller 5 min in GZ).  The last step to run was step 1 (CMS hagent).",
        "20200928",
        "153434",
        "6",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{BFFB963B-332C-4EE1-AF06-EC8D8C2796DD}",
        "SSRS BO-Tool Report DL",
        "1",
        "20200928",
        "175600",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 81 (Mo-So 15 Uhr).  The last step to run was step 1 (SSRS BO-Tool Report DL).",
        "20200928",
        "145600",
        "0",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{BFFB963B-332C-4EE1-AF06-EC8D8C2796DD}",
        "SSRS BO-Tool Report DL",
        "1",
        "20200928",
        "195600",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 81 (Mo-So 15 Uhr).  The last step to run was step 1 (SSRS BO-Tool Report DL).",
        "20200928",
        "145600",
        "0",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{BFFB963B-332C-4EE1-AF06-EC8D8C2796DD}",
        "SSRS BO-Tool Report DL",
        "1",
        "20200928",
        "215600",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 81 (Mo-So 15 Uhr).  The last step to run was step 1 (SSRS BO-Tool Report DL).",
        "20200928",
        "145600",
        "0",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{BFFB963B-332C-4EE1-AF06-EC8D8C2796DD}",
        "SSRS BO-Tool Report DL",
        "1",
        "20200929",
        "115600",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 81 (Mo-So 15 Uhr).  The last step to run was step 1 (SSRS BO-Tool Report DL).",
        "20200928",
        "145600",
        "0",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{BFFB963B-332C-4EE1-AF06-EC8D8C2796DD}",
        "SSRS BO-Tool Report DL",
        "1",
        "20200929",
        "145600",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 81 (Mo-So 15 Uhr).  The last step to run was step 1 (SSRS BO-Tool Report DL).",
        "20200928",
        "145600",
        "0",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{3E0CEFB9-DCCD-43E7-BF86-F1406AB5E318}",
        "SSRS AIC Report DL",
        "1",
        "20200928",
        "160000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 16 (Mo-So 07-23 Uhr).  The last step to run was step 1 (SSRS AIC Report DL).",
        "20200928",
        "150000",
        "0",
        "1",
        "2020-09-28 15:37:36",
    ],
    [
        "{35572CF3-551F-4216-84E7-FCEC2A2FE508}",
        "14 Uhr",
        "1",
        "20200929",
        "140500",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 46 (Mo-So 14:00).  The last step to run was step 2 (Aktivitaeten).",
        "20200928",
        "140500",
        "758",
        "1",
        "2020-09-28 15:37:36",
    ],
]

_STRING_TABLE_MULTIPLE_INSTANCES = [
    ["SERVICES"],
    [
        "{EEE97E08-D37D-45B0-8140-517270078907}",
        "CommandLog Cleanup",
        "1",
        "20241222",
        "0",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 16 (WeeklyCommandLog).  The last step to run was step 1 (CommandLog Cleanup).",
        "20241215",
        "0",
        "1",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{E27A4A40-74DE-4414-BADF-7DF74C49A690}",
        "DatabaseBackup - SYSTEM_DATABASES - FULL",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{EF94B88D-F12D-488C-9A42-213544089DDD}",
        "DatabaseBackup - USER_DATABASES - DIFF",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{30414067-A664-4D28-83D5-26B4F20C1EDA}",
        "DatabaseBackup - USER_DATABASES - FULL",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{71F46DF0-7674-43E4-8B55-FDD4C89BC62D}",
        "DatabaseBackup - USER_DATABASES - LOG",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{A11906F8-DF78-4323-B1C5-C4E5E56992B0}",
        "DatabaseIntegrityCheck - SYSTEM_DATABASES",
        "1",
        "20241222",
        "10000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 14 (WeeklyIntegritySystemDataases).  The last step to run was step 1 (DatabaseIntegrityCheck - SYSTEM_DATABASES).",
        "20241215",
        "10000",
        "5",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{CD343539-04F6-4ABD-B92E-FA230A720815}",
        "DatabaseIntegrityCheck - USER_DATABASES",
        "1",
        "20241222",
        "11000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 15 (WeeklyIntegrityUserDatbases).  The last step to run was step 1 (DatabaseIntegrityCheck - USER_DATABASES).",
        "20241215",
        "11000",
        "1301",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{9868AB93-1BD8-4D8E-A0E7-CBF02A44B3FD}",
        "FullBackup.FullBackup",
        "1",
        "20241219",
        "200000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 9 (FullBackup.FullBackup).  The last step to run was step 1 (FullBackup).",
        "20241218",
        "200000",
        "1222",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{300A7934-A991-4CA7-94C4-5AE3CEB7D11E}",
        "IndexOptimize - USER_DATABASES",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{99F8BF0B-E6D2-4630-BBDC-871EA5D1E988}",
        "JobRouter_Start_ABB_Kreditorenprozess",
        "1",
        "20241219",
        "54000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 11 (Alle 2 Minuten).  The last step to run was step 1 (Start Process).",
        "20241219",
        "55800",
        "13",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{4E0F9DB2-91D4-4739-843C-A7D5128ECE66}",
        "JobRouter_Start_LBB_Kreditorenprozess",
        "1",
        "20241219",
        "54000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 12 (Alle 2 Minuten).  The last step to run was step 1 (Start Process).",
        "20241219",
        "55800",
        "21",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{397221A0-7176-44B4-80F4-C5355FE12543}",
        "JobRouter_Stellvertretung_setzen_erlauben",
        "1",
        "20241219",
        "60000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 13 (Täglich jede Stunde).  The last step to run was step 1 (JRUSERS Tabelle updaten).",
        "20241219",
        "50000",
        "0",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{B9E51F6C-225C-45FD-B54C-544335C44B3E}",
        "Output File Cleanup",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{DFD77586-895C-4A53-9281-3065D1C5DAAC}",
        "sp_delete_backuphistory",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{7F3BB0E7-C582-473D-86AB-8185D076D9DA}",
        "sp_purge_jobhistory",
        "0",
        "",
        "",
        "5",
        "",
        "0",
        "0",
        "0",
        "",
        "2024-12-19 05:59:37",
    ],
    [
        "{6F578981-C22E-45CC-99AF-857BED9A593B}",
        "syspolicy_purge_history",
        "1",
        "20241220",
        "20000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 8 (syspolicy_purge_history_schedule).  The last step to run was step 3 (Erase Phantom System Health Records.).",
        "20241219",
        "20000",
        "4",
        "1",
        "2024-12-19 05:59:37",
    ],
    [
        "{9FB3ABD1-584E-45EA-B99A-FDA48CE26A1C}",
        "TLog.TLog",
        "1",
        "20241219",
        "60000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 10 (TLog.TLog).  The last step to run was step 1 (TLog).",
        "20241219",
        "50000",
        "19",
        "1",
        "2024-12-19 05:59:37",
    ],
    ["PROTEL"],
    [
        "{36684481-8BB6-4003-9040-3CA97E6552E2}",
        "DatabaseIntegrityCheck - SYSTEM_DATABASES",
        "1",
        "20241222",
        "30100",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 13 (WeeklyIntegritySystemDataases).  The last step to run was step 1 (DatabaseIntegrityCheck - SYSTEM_DATABASES).",
        "20241215",
        "30100",
        "2",
        "1",
        "2024-12-19 05:59:39",
    ],
    [
        "{55DA288E-EF7A-48C2-B176-AB3B1FBA501F}",
        "DatabaseIntegrityCheck - USER_DATABASES",
        "1",
        "20241222",
        "31000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 14 (WeeklyIntegrityUserDatbases).  The last step to run was step 1 (DatabaseIntegrityCheck - USER_DATABASES).",
        "20241215",
        "31000",
        "130",
        "1",
        "2024-12-19 05:59:39",
    ],
    [
        "{D2B8A160-676E-4EE3-946A-6CFC4BD3B5DA}",
        "FullBackup.FullBackup",
        "1",
        "20241219",
        "200000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 9 (FullBackup.FullBackup).  The last step to run was step 1 (FullBackup).",
        "20241218",
        "200000",
        "46",
        "1",
        "2024-12-19 05:59:39",
    ],
    [
        "{07D35480-582B-4368-A62C-3CF61CB2ED80}",
        "syspolicy_purge_history",
        "1",
        "20241220",
        "20000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 8 (syspolicy_purge_history_schedule).  The last step to run was step 3 (Erase Phantom System Health Records.).",
        "20241219",
        "20000",
        "6",
        "1",
        "2024-12-19 05:59:39",
    ],
    [
        "{C1BFDA1A-E574-47E5-B804-7B98960A7876}",
        "TLog.TLog",
        "1",
        "20241219",
        "60000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 10 (TLog.TLog).  The last step to run was step 1 (TLog).",
        "20241219",
        "50001",
        "5",
        "1",
        "2024-12-19 05:59:39",
    ],
    ["TCPOS"],
    [
        "{A7ACFD53-F4FB-4542-AC43-A8F2DCB4D71B}",
        "syspolicy_purge_history",
        "1",
        "20241220",
        "20000",
        "1",
        "The job succeeded.  The Job was invoked by Schedule 8 (syspolicy_purge_history_schedule).  The last step to run was step 3 (Erase Phantom System Health Records.).",
        "20241219",
        "20000",
        "6",
        "1",
        "2024-12-19 05:59:41",
    ],
]


_STRING_TABLE_ERROR = [
    [
        "MSSQLSERVER ERROR: The SELECT permission was denied on the object 'sysschedules', database 'msdb', schema 'dbo'. (SQLState: 42000/NativeError: 229)."
    ]
]


def test_discover_single_instance_single_job() -> None:
    assert list(
        discover_mssql_jobs(parse_mssql_jobs(_make_job(enabled=True, scheduled=False)))
    ) == [
        Service(item="teststsssss - MSSQLSERVER"),
    ]


def test_discover_single_instance_multiple_jobs() -> None:
    assert list(
        discover_mssql_jobs(parse_mssql_jobs(_STRING_TABLE_SINGLE_INSTANCE_MULTIPLE_JOBS))
    ) == [
        Service(item="täglich 00:03 - MSSQLSERVER"),
        Service(item="4x Täglich Infomanagement - MSSQLSERVER"),
        Service(item="Wartung Stündlich - MSSQLSERVER"),
        Service(item="1x Täglich - MSSQLSERVER"),
        Service(item="aller 2h - MSSQLSERVER"),
        Service(item="Wartung Täglich - MSSQLSERVER"),
        Service(item="1x Täglich 6:00 Uhr - MSSQLSERVER"),
        Service(item="1x Täglich Infomanagement - MSSQLSERVER"),
        Service(item="Sonntag - MSSQLSERVER"),
        Service(item="SSIS Server Maintenance Job - MSSQLSERVER"),
        Service(item="aller 1h - MSSQLSERVER"),
        Service(item="1 x täglich 01:00 Uhr - MSSQLSERVER"),
        Service(item="1x täglich ttCall - MSSQLSERVER"),
        Service(item="aller 15 min - MSSQLSERVER"),
        Service(item="aller 5 min - MSSQLSERVER"),
        Service(item="SSRS BO-Tool Report DL - MSSQLSERVER"),
        Service(item="SSRS AIC Report DL - MSSQLSERVER"),
        Service(item="14 Uhr - MSSQLSERVER"),
    ]


def test_discover_multiple_instances() -> None:
    assert list(discover_mssql_jobs(parse_mssql_jobs(_STRING_TABLE_MULTIPLE_INSTANCES))) == [
        Service(item="CommandLog Cleanup - SERVICES"),
        Service(item="DatabaseBackup - SYSTEM_DATABASES - FULL - SERVICES"),
        Service(item="DatabaseBackup - USER_DATABASES - DIFF - SERVICES"),
        Service(item="DatabaseBackup - USER_DATABASES - FULL - SERVICES"),
        Service(item="DatabaseBackup - USER_DATABASES - LOG - SERVICES"),
        Service(item="DatabaseIntegrityCheck - SYSTEM_DATABASES - SERVICES"),
        Service(item="DatabaseIntegrityCheck - USER_DATABASES - SERVICES"),
        Service(item="FullBackup.FullBackup - SERVICES"),
        Service(item="IndexOptimize - USER_DATABASES - SERVICES"),
        Service(item="JobRouter_Start_ABB_Kreditorenprozess - SERVICES"),
        Service(item="JobRouter_Start_LBB_Kreditorenprozess - SERVICES"),
        Service(item="JobRouter_Stellvertretung_setzen_erlauben - SERVICES"),
        Service(item="Output File Cleanup - SERVICES"),
        Service(item="sp_delete_backuphistory - SERVICES"),
        Service(item="sp_purge_jobhistory - SERVICES"),
        Service(item="syspolicy_purge_history - SERVICES"),
        Service(item="TLog.TLog - SERVICES"),
        Service(item="DatabaseIntegrityCheck - SYSTEM_DATABASES - PROTEL"),
        Service(item="DatabaseIntegrityCheck - USER_DATABASES - PROTEL"),
        Service(item="FullBackup.FullBackup - PROTEL"),
        Service(item="syspolicy_purge_history - PROTEL"),
        Service(item="TLog.TLog - PROTEL"),
        Service(item="syspolicy_purge_history - TCPOS"),
    ]


def test_discover_error() -> None:
    assert not list(discover_mssql_jobs(parse_mssql_jobs(_STRING_TABLE_ERROR)))


@pytest.mark.parametrize(
    "job, status, expected_state, expected_result",
    [
        (_make_job(enabled=False, scheduled=False), 0, State.OK, "Job is disabled"),
        (_make_job(enabled=True, scheduled=False), 0, State.OK, "Schedule is disabled"),
        (_make_job(enabled=True, scheduled=True), 0, State.OK, "Next run: N/A"),
        (_make_job(enabled=True, scheduled=False), 1, State.WARN, "Schedule is disabled"),
        (_make_job(enabled=True, scheduled=True), 1, State.OK, "Next run: N/A"),
    ],
)
def test_check_schedule(
    job: StringTable, status: int, expected_state: State, expected_result: str
) -> None:
    assert list(
        check_mssql_jobs(
            "teststsssss - MSSQLSERVER",
            {
                "consider_job_status": "ignore",
                "status_disabled_jobs": 0,
                "status_disabled_schedule": status,
                "status_missing_jobs": 2,
                "run_duration": None,
            },
            parse_mssql_jobs(job),
        )
    ) == [
        Result(state=State.OK, summary="Last duration: 0 seconds"),
        Metric("database_job_duration", 0.0),
        Result(state=State.OK, summary="MSSQL status: Unknown"),
        Result(state=State.OK, summary="Last run: N/A"),
        Result(state=expected_state, summary=expected_result),
        Result(state=State.OK, notice="Outcome message: "),
    ]


@pytest.mark.parametrize(
    "job, status, expected_state, expected_result",
    [
        (_make_job(enabled=False, scheduled=False), 0, State.OK, "Job is disabled"),
        (_make_job(enabled=False, scheduled=False), 1, State.WARN, "Job is disabled"),
        (_make_job(enabled=True, scheduled=False), 0, State.OK, "Schedule is disabled"),
        (_make_job(enabled=True, scheduled=False), 2, State.CRIT, "Schedule is disabled"),
        (_make_job(enabled=False, scheduled=True), 2, State.CRIT, "Job is disabled"),
        (_make_job(enabled=True, scheduled=True), 2, State.OK, "Next run: N/A"),
    ],
)
def test_check_job(
    job: StringTable, status: int, expected_state: State, expected_result: str
) -> None:
    assert list(
        check_mssql_jobs(
            "teststsssss - MSSQLSERVER",
            {
                "consider_job_status": "ignore",
                "status_disabled_jobs": status,
                "status_disabled_schedule": status,
                "status_missing_jobs": 2,
                "run_duration": None,
            },
            parse_mssql_jobs(job),
        )
    )[4] == Result(state=expected_state, summary=expected_result)


def test_check_failure() -> None:
    assert list(
        check_mssql_jobs(
            "Wartung Stündlich - MSSQLSERVER",
            {
                "consider_job_status": "consider",
                "status_disabled_jobs": 1,
                "status_disabled_schedule": 0,
                "status_missing_jobs": 2,
                "run_duration": (1800, 2400),
            },
            parse_mssql_jobs(_STRING_TABLE_SINGLE_INSTANCE_MULTIPLE_JOBS),
        )
    ) == [
        Result(state=State.OK, summary="Last duration: 9 seconds"),
        Metric("database_job_duration", 9.0, levels=(1800.0, 2400.0)),
        Result(state=State.CRIT, summary="MSSQL status: Fail"),
        Result(state=State.OK, summary="Last run: 2020-09-28 15:15:00"),
        Result(state=State.OK, summary="Next run: 2020-09-28 16:15:00"),
        Result(
            state=State.OK,
            notice=(
                "Outcome message: The job failed.  JobManager tried to run a non-existent"
                " step (3) for job Wartung Stündlich."
            ),
        ),
    ]


def test_check_with_outcome_message() -> None:
    assert list(
        check_mssql_jobs(
            "aller 2h - MSSQLSERVER",
            {
                "consider_job_status": "ignore",
                "status_disabled_jobs": 0,
                "status_disabled_schedule": 0,
                "status_missing_jobs": 2,
                "run_duration": (1800, 2400),
            },
            parse_mssql_jobs(_STRING_TABLE_SINGLE_INSTANCE_MULTIPLE_JOBS),
        )
    ) == [
        Result(state=State.OK, summary="Last duration: 12 minutes 45 seconds"),
        Metric("database_job_duration", 765.0, levels=(1800.0, 2400.0)),
        Result(state=State.OK, summary="MSSQL status: Succeed"),
        Result(state=State.OK, summary="Last run: 2020-09-28 15:05:01"),
        Result(state=State.OK, summary="Next run: 2020-09-28 17:05:00"),
        Result(
            state=State.OK,
            notice=(
                "Outcome message: The job succeeded.  The Job was invoked by Schedule 48 (Mo-"
                "Sa 07:00 aller 2h).  The last step to run was step 2 (Magicinfo_Device_IP)."
            ),
        ),
    ]


@pytest.mark.parametrize(
    "string_table, item, params, expected_result",
    [
        pytest.param(
            [
                ["MSSQLSERVER"],
                [
                    "{ABC-1234}",
                    "MyJob",
                    "0",
                    "20221226",
                    "40000",
                    "5",
                    "An error occurred.",
                    "20221219",
                    "40000",
                    "0",
                    "0",
                    "2022-12-23 08:52:50",
                ],
            ],
            "MyJob - MSSQLSERVER",
            {
                "consider_job_status": "consider_if_enabled",
                "status_disabled_jobs": 0,
                "status_disabled_schedule": 0,
                "status_missing_jobs": 2,
            },
            [
                Result(state=State.OK, summary="Last duration: 0 seconds"),
                Metric("database_job_duration", 0.0),
                Result(state=State.OK, summary="MSSQL status: Unknown"),
                Result(state=State.OK, summary="Last run: 2022-12-19 04:00:00"),
                Result(state=State.OK, summary="Job is disabled"),
                Result(state=State.OK, notice="Outcome message: An error occurred."),
            ],
            id="consider_if_enabled on, job disabled",
        ),
        pytest.param(
            [
                ["MSSQLSERVER"],
                [
                    "{ABC-1234}",
                    "MyJob",
                    "1",
                    "20221226",
                    "40000",
                    "5",
                    "An error occurred.",
                    "20221219",
                    "40000",
                    "0",
                    "0",
                    "2022-12-23 08:52:50",
                ],
            ],
            "MyJob - MSSQLSERVER",
            {
                "consider_job_status": "consider_if_enabled",
                "status_disabled_jobs": 0,
                "status_disabled_schedule": 0,
                "status_missing_jobs": 2,
            },
            [
                Result(state=State.OK, summary="Last duration: 0 seconds"),
                Metric("database_job_duration", 0.0),
                Result(state=State.UNKNOWN, summary="MSSQL status: Unknown"),
                Result(state=State.OK, summary="Last run: 2022-12-19 04:00:00"),
                Result(state=State.OK, summary="Schedule is disabled"),
                Result(state=State.OK, notice="Outcome message: An error occurred."),
            ],
            id="consider_if_enabled on, job enabled",
        ),
    ],
)
def test_check_mssql_jobs_consider_if_enabled(
    string_table: StringTable,
    item: str,
    params: Mapping[str, object],
    expected_result: CheckResult,
) -> None:
    section = parse_mssql_jobs(string_table)

    assert list(check_mssql_jobs(item, params, section)) == expected_result
